package modules

import (
	"net/http"
	"config"
	"utils"
	"github.com/PuerkitoBio/goquery"
	"showSdk/normalRequest"
	"fmt"
	"encoding/base64"
	"io/ioutil"
	"strings"
	"encoding/json"
	"os"
	"bytes"
	"sync"
	"time"
	"net/url"
)

const (
	ACCOUNT_KEY  = "txt_U_name"
	PASSWORD_KEY = "txt_U_Password"
	VER_CODE_KEY = "txt_validate"

	__VIEWSTATEGENERATOR       = "__VIEWSTATEGENERATOR"
	__VIEWSTATE                = "__VIEWSTATE"
	__RequestVerificationToken = "__RequestVerificationToken"
)

var one sync.Once
var a *http.Client

type LoginKeep struct {
	memberLoginHost string //会员登陆界面的host,例如:http://65xjdgw.bx3618.com/cp-2-mb/
	loginAction     string //会员登陆的action
	cookies         []*http.Cookie
	loginBodys      []string

	realLoginUrl string

	indexCookies []*http.Cookie
}

// 获取http客户端对象
func getClient() *http.Client {
	timeout := time.Duration(32 * time.Second) //超时时间32秒
	a = &http.Client{
		Timeout: timeout,
	}
	one.Do(func() {

	})
	return a
}

// 打开首页
func (m *LoginKeep) OpenIndex() {
	curUrl := config.MyConfig.RootUrl
	requst, err := http.NewRequest(http.MethodGet, curUrl, nil)
	if err != nil {

	}
	resp, err := getClient().Do(requst)
	m.indexCookies = resp.Cookies()
}

// 首页搜索
func (m *LoginKeep) Search() (string, error) {
	curUrl := config.MyConfig.RootUrl + "search.aspx"
	bodyStr := "wd=" + config.MyConfig.SearchCode //搜索码
	fmt.Println("搜索数据", bodyStr)
	bodyReader := strings.NewReader(bodyStr)
	request, err := http.NewRequest(http.MethodPost, curUrl, bodyReader)
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	if err != nil {

	}
	for _, cookie := range m.indexCookies {
		request.AddCookie(cookie)
	}
	resp, err := getClient().Do(request)
	if err != nil {

	}
	defer resp.Body.Close()

	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
	}
	toIndexUrl, b := doc.Find("body").Find("iframe").Attr("src")
	if !b {

	}
	if len(toIndexUrl) > 0 {
		lastIndex := strings.LastIndex(toIndexUrl, "/") // 最后的斜杠下标
		if lastIndex > 0 {
			fmt.Println(toIndexUrl)
			m.memberLoginHost = toIndexUrl[:lastIndex+1]
		}
	}
	if m.memberLoginHost == "" {
		//err
	}
	toIndexUrl = strings.Replace(toIndexUrl, ":80", "", 1)
	toIndexUrl = strings.Replace(toIndexUrl, "&wd=66392", "", 1)
	m.realLoginUrl = toIndexUrl
	return toIndexUrl, nil
}

//获取会员登陆页面数据
func (m *LoginKeep) GetLoginPage() {
	curUrl := m.realLoginUrl
	fmt.Println("跳登陆:", curUrl)
	request, err := http.NewRequest(http.MethodGet, curUrl, nil)
	request.Header.Set("Referer", config.MyConfig.RootUrl+"search.aspx")
	setUserAgent(request)
	//request.Header.Set("Host", "47nfdgw.bx3618.com")
	if err != nil {
	}
	resp, err := getClient().Do(request)
	if err != nil {
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {

	}
	resp.Body = ioutil.NopCloser(bytes.NewReader(body))

	doc, err := goquery.NewDocumentFromReader(resp.Body)
	if err != nil {
	}
	//保存cookie:获取验证码和登陆都需要
	m.cookies = resp.Cookies()
	//拼接登陆的url
	loginUrl, b := doc.Find("body").Find("form").Attr("action")
	//fmt.Println(loginUrl, b)
	if b && len(loginUrl) > 0 {
		firstIndex := strings.Index(loginUrl, "?") // 最后的斜杠下标
		if firstIndex > 0 {
			m.loginAction = loginUrl[firstIndex:]
		}
		endIndex := strings.LastIndex(m.loginAction, "&wd")
		if endIndex > 0 {
			m.loginAction = m.loginAction[:endIndex]
		}
	}

	imgPath := utils.GetTempPagePath()
	os.Remove(imgPath)
	fd, _ := os.OpenFile(imgPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	fd.Write(body)
	//拼接登陆中的form内容
	for i := 0; i < 3; i++ {
		input := doc.Find("body").Find("form").Find("input").Eq(i)
		key, _ := input.Attr("name")
		val, _ := input.Attr("value")
		if key == __VIEWSTATE || key == __RequestVerificationToken {
			if key == __VIEWSTATE {
				if val[len(val)-3:]!="+0=" {
					//val = "/wEPDwUKLTEyNTYwMjE1MGRkJfZO3MPFVzoETEYVbCKBhz3VEFKYoFVHGsrqBHsYK+0="
					//return
				}
			}
			m.loginBodys = append(m.loginBodys, key+"="+url.QueryEscape(val))

		}
	}
	m.loginBodys = append(m.loginBodys, __VIEWSTATEGENERATOR+"=87219E81")
}

//获取base64格式的验证码
func (m *LoginKeep) GetCode() (string, error) {
	imgCodeUrl := fmt.Sprintf(m.memberLoginHost+"checknum.aspx?ts=%d", utils.GetNowTimestamp13())
	fmt.Println("获取验证码:", imgCodeUrl)
	request, err := http.NewRequest(http.MethodGet, imgCodeUrl, nil)
	if err != nil {

	}
	for _, cookie := range m.cookies {
		request.AddCookie(cookie)
	}
	request.Header.Set("Referer", m.realLoginUrl)
	setUserAgent(request)
	request.Header.Set("Accept", "image/webp,image/apng,image/*,*/*;q=0.8")
	request.Header.Set("Accept-Encoding", "gzip, deflate")
	request.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7")
	resp, err := getClient().Do(request)
	if err != nil {
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {

	}
	// 目前不需要存储为图片了,存为图片只是为了人工比较是否验证错误
	imgPath := utils.GetTempImgPath()
	os.Remove(imgPath)
	fd, _ := os.OpenFile(imgPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	fd.Write(body)
	base64img := base64.StdEncoding.EncodeToString(body)
	return base64img, nil
}

//过验证码
// base64img
func (m *LoginKeep) CheckCode(base64img string) (string, error) {
	//encodeString = strings.Replace(encodeString, "\\", "%2F", -1)
	//encodeString = strings.Replace(encodeString, "/", "%2F", -1)
	//appid he sign
	res := normalRequest.ShowapiRequest(config.MyConfig.ReqUrl, config.MyConfig.AppId, config.MyConfig.Sign)
	res.AddTextPara("img_base64", base64img)
	res.AddTextPara("typeId", "14")
	resp, err := res.Get()
	if err != nil {
		return "", err
	}
	respStruct := struct {
		ShowapiResCode  int    `json:"showapi_res_code"`
		ShowapiResError string `json:"showapi_res_error"`
		ShowapiResBody struct {
			Result string `json:"Result"`
		} `json:"showapi_res_body"`
	}{}
	err = json.Unmarshal([]byte(resp), &respStruct)
	if err != nil {
		return "", err
	}
	if respStruct.ShowapiResError == "" && respStruct.ShowapiResBody.Result != "" {
		fmt.Println("过验证码:", respStruct.ShowapiResBody.Result)
		return respStruct.ShowapiResBody.Result, nil
	} else {
		fmt.Println("没钱了", respStruct.ShowapiResError)
	}
	return "", err
}

// 登陆
func (m *LoginKeep) Login(verCode string) {
	curUrl := m.realLoginUrl
	//curUrl := strings.Replace(m.realLoginUrl, "cp-2-mb/", "cp-2-mb/indexmb.aspx", 1)
	//curUrl = strings.Replace(curUrl, "&", "&amp;", -1)
	fmt.Println("地址:", curUrl)
	account := config.MyConfig.Account
	password := config.MyConfig.Password
	m.loginBodys = append(m.loginBodys, ACCOUNT_KEY+"="+account)
	m.loginBodys = append(m.loginBodys, PASSWORD_KEY+"="+password)
	m.loginBodys = append(m.loginBodys, VER_CODE_KEY+"="+verCode)

	bodyStr := strings.Join(m.loginBodys, "&")
	fmt.Println(bodyStr)
	bodyReader := strings.NewReader(bodyStr)
	request, err := http.NewRequest(http.MethodPost, curUrl, bodyReader)
	if err != nil {
	}

	for _, cookie := range m.cookies {
		fmt.Printf("这是我的cookie: %s=%s\n", cookie.Name, cookie.Value)
		request.AddCookie(cookie)
	}
	request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	request.Header.Set("Pragma", "no-cache")
	request.Header.Set("Referer", curUrl)
	request.Header.Set("Origin", utils.GetOrigin(curUrl))
	request.Header.Set("Upgrade-Insecure-Requests", "1")
	request.Header.Set("Cache-Control", "no-cache")
	request.Header.Set("Connection", "keep-alive")
	setUserAgent(request)
	request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8")
	//request.Header.Set("Accept-Encoding", "gzip, deflate")
	request.Header.Set("Accept-Language", "zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7")
	resp, err := getClient().Do(request)
	if err != nil {

	}
	defer resp.Body.Close()
	x, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(x))

}

func setUserAgent(request *http.Request) {
	request.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3432.3 Safari/537.36")
	request.Header.Set("Accept-Language","zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7")

}
